package com.example.javapoet.demo.advanced;

import com.squareup.javapoet.*;
import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * JavaPoet高级示例 - 生成Builder模式代码
 */
public class BuilderPatternGeneration {

    public static void main(String[] args) {
        // 生成Builder模式类
        generateBuilderClass();
    }

    /**
     * 生成Builder模式类
     */
    public static void generateBuilderClass() {
        // 创建Person类
        TypeSpec personClass = createPersonClass();
        
        // 创建Java文件
        JavaFile javaFile = JavaFile.builder("com.example.builder", personClass)
                .build();

        try {
            // 输出到控制台
            System.out.println("生成Person类（带Builder模式）:");
            javaFile.writeTo(System.out);
            
            // 输出到文件
            Path path = Paths.get("src/main/java");
            javaFile.writeTo(new File(path.toUri()));
            System.out.println("成功生成Person.java文件");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建Person类
     */
    private static TypeSpec createPersonClass() {
        // 创建字段
        FieldSpec idField = FieldSpec.builder(long.class, "id")
                .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
                .build();
        
        FieldSpec nameField = FieldSpec.builder(String.class, "name")
                .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
                .build();
        
        FieldSpec ageField = FieldSpec.builder(int.class, "age")
                .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
                .build();
        
        FieldSpec emailField = FieldSpec.builder(String.class, "email")
                .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
                .build();
        
        // 创建Builder类
        TypeSpec builderClass = TypeSpec.classBuilder("Builder")
                .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                .addField(FieldSpec.builder(long.class, "id")
                        .addModifiers(Modifier.PRIVATE)
                        .build())
                .addField(FieldSpec.builder(String.class, "name")
                        .addModifiers(Modifier.PRIVATE)
                        .build())
                .addField(FieldSpec.builder(int.class, "age")
                        .addModifiers(Modifier.PRIVATE)
                        .build())
                .addField(FieldSpec.builder(String.class, "email")
                        .addModifiers(Modifier.PRIVATE)
                        .build())
                .addMethod(MethodSpec.methodBuilder("id")
                        .addModifiers(Modifier.PUBLIC)
                        .returns(ClassName.get("", "Builder"))
                        .addParameter(long.class, "id")
                        .addStatement("this.id = id")
                        .addStatement("return this")
                        .build())
                .addMethod(MethodSpec.methodBuilder("name")
                        .addModifiers(Modifier.PUBLIC)
                        .returns(ClassName.get("", "Builder"))
                        .addParameter(String.class, "name")
                        .addStatement("this.name = name")
                        .addStatement("return this")
                        .build())
                .addMethod(MethodSpec.methodBuilder("age")
                        .addModifiers(Modifier.PUBLIC)
                        .returns(ClassName.get("", "Builder"))
                        .addParameter(int.class, "age")
                        .addStatement("this.age = age")
                        .addStatement("return this")
                        .build())
                .addMethod(MethodSpec.methodBuilder("email")
                        .addModifiers(Modifier.PUBLIC)
                        .returns(ClassName.get("", "Builder"))
                        .addParameter(String.class, "email")
                        .addStatement("this.email = email")
                        .addStatement("return this")
                        .build())
                .addMethod(MethodSpec.methodBuilder("build")
                        .addModifiers(Modifier.PUBLIC)
                        .returns(ClassName.get("com.example.builder", "Person"))
                        .addStatement("return new Person(this.id, this.name, this.age, this.email)")
                        .build())
                .build();
        
        // 创建私有构造函数
        MethodSpec constructor = MethodSpec.constructorBuilder()
                .addModifiers(Modifier.PRIVATE)
                .addParameter(long.class, "id")
                .addParameter(String.class, "name")
                .addParameter(int.class, "age")
                .addParameter(String.class, "email")
                .addStatement("this.id = id")
                .addStatement("this.name = name")
                .addStatement("this.age = age")
                .addStatement("this.email = email")
                .build();
        
        // 创建静态builder方法
        MethodSpec builderMethod = MethodSpec.methodBuilder("builder")
                .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                .returns(ClassName.get("com.example.builder", "Person", "Builder"))
                .addStatement("return new Builder()")
                .build();
        
        // 创建getter方法
        MethodSpec getIdMethod = MethodSpec.methodBuilder("getId")
                .addModifiers(Modifier.PUBLIC)
                .returns(long.class)
                .addStatement("return id")
                .build();
        
        MethodSpec getNameMethod = MethodSpec.methodBuilder("getName")
                .addModifiers(Modifier.PUBLIC)
                .returns(String.class)
                .addStatement("return name")
                .build();
        
        MethodSpec getAgeMethod = MethodSpec.methodBuilder("getAge")
                .addModifiers(Modifier.PUBLIC)
                .returns(int.class)
                .addStatement("return age")
                .build();
        
        MethodSpec getEmailMethod = MethodSpec.methodBuilder("getEmail")
                .addModifiers(Modifier.PUBLIC)
                .returns(String.class)
                .addStatement("return email")
                .build();
        
        // 创建toString方法
        MethodSpec toStringMethod = MethodSpec.methodBuilder("toString")
                .addAnnotation(Override.class)
                .addModifiers(Modifier.PUBLIC)
                .returns(String.class)
                .addStatement("return $S + id + $S + name + $S + age + $S + email + $S", 
                        "Person{id=", ", name='", "', age=", ", email='", "'}")
                .build();
        
        // 构建Person类
        return TypeSpec.classBuilder("Person")
                .addModifiers(Modifier.PUBLIC)
                .addField(idField)
                .addField(nameField)
                .addField(ageField)
                .addField(emailField)
                .addType(builderClass)
                .addMethod(constructor)
                .addMethod(builderMethod)
                .addMethod(getIdMethod)
                .addMethod(getNameMethod)
                .addMethod(getAgeMethod)
                .addMethod(getEmailMethod)
                .addMethod(toStringMethod)
                .build();
    }
}